package org.dromara.common.web.config;

import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.web.config.properties.XssProperties;
import org.dromara.common.web.filter.RepeatableFilter;
import org.dromara.common.web.filter.XssFilter;
import jakarta.servlet.DispatcherType;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

import java.util.HashMap;
import java.util.Map;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：Filter配置
 */
@AutoConfiguration
@EnableConfigurationProperties(XssProperties.class)
public class FilterConfig {

    /**
     * 条件性地创建并注册XSS过滤器
     * 该方法仅在配置属性"xss.enabled"为true时生效，用于防御XSS攻击
     *
     * @param xssProperties 包含XSS过滤器相关配置属性的对象
     * @return 返回配置好的FilterRegistrationBean对象，用于注册XssFilter
     *
     * 此处注解@Bean标明这是一个Spring管理的Bean组件
     * @ConditionalOnProperty则表示该组件的创建依赖于指定的配置属性值
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    @Bean
    // 当配置属性"xss.enabled"为true时，启用XSS过滤器
    @ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
    public FilterRegistrationBean xssFilterRegistration(XssProperties xssProperties) {
        // 创建一个新的FilterRegistrationBean实例用于配置XSS过滤器
        FilterRegistrationBean registration = new FilterRegistrationBean();

        // 设置过滤器的类型为请求，意味着它只在请求进入时执行
        registration.setDispatcherTypes(DispatcherType.REQUEST);

        // 设置需要注册的过滤器实例为XssFilter
        registration.setFilter(new XssFilter());

        // 根据配置的URL模式列表添加需要过滤的URL模式
        registration.addUrlPatterns(StringUtils.split(xssProperties.getUrlPatterns(), StringUtils.SEPARATOR));

        // 设置过滤器的名称
        registration.setName("xssFilter");

        // 设置过滤器的优先级，值越小优先级越高
        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);

        // 初始化参数集合，用于配置过滤器的初始参数
        Map<String, String> initParameters = new HashMap<>();

        // 设置排除的URL模式列表作为初始化参数之一
        initParameters.put("excludes", xssProperties.getExcludes());

        // 设置过滤器的初始化参数
        registration.setInitParameters(initParameters);

        // 返回配置好的过滤器注册对象
        return registration;
    }

    /**
     * 注册一个过滤器到应用中
     *
     * @return FilterRegistrationBean 对象，包含了过滤器的配置
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    @Bean
    public FilterRegistrationBean someFilterRegistration() {
        // 创建一个新的过滤器注册对象
        FilterRegistrationBean registration = new FilterRegistrationBean();
        // 设置过滤器为新的RepeatableFilter实例
        registration.setFilter(new RepeatableFilter());
        // 添加匹配的所有URL模式，表示该过滤器将应用于所有请求
        registration.addUrlPatterns("/*");
        // 设置过滤器的名称
        registration.setName("repeatableFilter");
        // 设置过滤器的执行顺序为最低优先级
        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
        // 返回配置好的过滤器注册对象
        return registration;
    }

}
